﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using ecdl.demo.model.question;
using ecdl.demo.model;
using Ninject;
using ecdl.demo.model.file;
using ecdl.demo.model.util;
using ecdl.demo.persistence;
using ecdl.demo.ui.ui.testselection;
using Moq;

namespace ecdl.demo.application {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application {

        private const bool _TEST_MODE = true ;
        //initialize Dipendency Injection Container
        private IKernel injector = new StandardKernel(new DemoTestModule()); 

        private Questionaire loadQuestionaire() {
            return Questionaire.GetDefaultQuestionaire();
        }

        void App_Startup(object sender, StartupEventArgs e) {
            // create new window and pass the tests to the window
            if (_TEST_MODE) {
                // load all tests into collection
                List<Test> allTests = CreateAllTests(injector.Get<ModelFactory>());

                TestSelectionWindow selectionWindow = new TestSelectionWindow(allTests);
                selectionWindow.TestSelectedEvent += new EventHandler<GenericEventArgs<Test>>(TestSelectedEvent);
                selectionWindow.Show();
            } else {
                ITestEvaluationPresenter presenter = injector.Get<ITestEvaluationPresenter>();
                presenter.ShowTestEvaluation(getTestEvaluations());
            }
        }

        private IList<TaskEvaluation> getTestEvaluations() {
            List<TaskEvaluation> evaluations = new List<TaskEvaluation>();

            evaluations.Add(new TaskEvaluation(createTask(2, "task1"), 1, "testCause1"));
            evaluations.Add(new TaskEvaluation(createTask(2, "task2"), 2, "testCause2"));
            evaluations.Add(new TaskEvaluation(createTask(3, "task3"), 3, "testCause3"));
            evaluations.Add(new TaskEvaluation(createTask(1, "task4"), 0, "testCause4"));
            return evaluations;
        }

        private ITask createTask(int p, string text) {
            FileTask task = new FileTask(injector.Get<ITaskPresenter>(), injector.Get<IVolumeProvider>());
            task.MaxPoints = p;
            task.Text = text;
            return task;
        }

        void TestSelectedEvent(object sender, GenericEventArgs<Test> e) {
            
            injector.Bind<Test>().ToConstant<Test>(e.Value);
            ((Window)sender).Close();
            TestRun run = injector.Get<TestRun>();
            run.Start();
        }

        private List<Test> CreateAllTests(persistence.ModelFactory factory) {

            List<Test> tests = new List<Test>();

            tests.Add(CreateGenericTest(factory, "ecdl.demo.application.res.test2.xml"));
            tests.Add(CreateGenericTest(factory, "ecdl.demo.application.res.test1.xml"));
            

            return tests;
        }

        private Test CreateGenericTest(persistence.ModelFactory factory, string fileuri) {
            System.IO.Stream stream = typeof(App).Assembly.GetManifestResourceStream(fileuri);

            var serializer = factory.CreateModel<GenericSerializer<TestDTO>>();
            TestDTO testDto = serializer.Deseriliaze(new System.IO.StreamReader(stream));

            Test currenTest = testDto.ToModel(factory);

            var resolver = factory.CreateModel<TaskPathResolver>();
            
            resolver.ResolveTask(currenTest.Tasks);

            return currenTest;
        }


        private Test CreateCurrentTest(persistence.ModelFactory factory, IEnumerable<ITaskProvider> taskProviders) {
            // load a list of questions

            //create an example test and add all questions to it
            Test test = new Test();
            var resolver = factory.CreateModel<TaskPathResolver>();
            foreach (var provider in taskProviders) {
                var tasks = provider.GetTasks(factory);
                resolver.ResolveTask(tasks);
                test.Tasks.AddRange(tasks);
            }
            return test;
        }
    }
}
